#pragma once
#include "..\\..\\ShiningloreTribes_v3\\ref\\rijndael\\rijndael-alg-fst.h"
#include "..\\..\\CmbChina\\CmbChina\\bot\\FileVersion.h"

#include <string>
#include <hash_set>
#include <algorithm>
#include <iostream>


void InitRand(int seed);
void DecryptPackage(char* buf, int len);
void EncryptPackage(char* buf, int len);
int CalculateHip(char* buf, int len);
int BuildHipFormular(char* buf, int len);

class ISymmetricCrypto
{
public:
	virtual bool setCipher(const unsigned char* cipher, const int length) = 0;
	virtual bool encrypt(const unsigned char* input, const int length, unsigned char* output) = 0;
	virtual bool decrypt(const unsigned char* input, const int length, unsigned char* output) = 0;
};

class RijndaelCrypto : public ISymmetricCrypto
{
public:
	RijndaelCrypto(bool encrypt);

	// cipher length must be 128 bits (16 bytes)
	virtual bool setCipher(const unsigned char* cipher, const int length);

	// data length must be 128 bits (16 bytes)
	virtual bool encrypt(const unsigned char* input, const int length, unsigned char* output);

	// data length must be 128 bits (16 bytes)
	virtual bool decrypt(const unsigned char* input, const int length, unsigned char* output);

private:
	bool m_encrypt;
	u32 m_rk[44];
};

class ShiningloreCryptoCache
{
public:
	static std::shared_ptr<ISymmetricCrypto> getRijndaelEncrypter();
	static std::shared_ptr<ISymmetricCrypto> getRijndaelDecrypter();

private:
	static std::shared_ptr<ISymmetricCrypto> s_encrypter;
	static std::shared_ptr<ISymmetricCrypto> s_decrypter;
};

class ShiningloreVersionCache
{
public:
	static std::shared_ptr<CFileVersion> getT509Ver();
	static std::shared_ptr<CFileVersion> getX509Ver();

private:
	static std::shared_ptr<CFileVersion> s_t509;
	static std::shared_ptr<CFileVersion> s_x509;
};